/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.debugger.support.nodes; import java.awt.Image; import java.awt.Toolkit; import java.beans.BeanInfo; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; import java.util.ResourceBundle; import java.util.HashMap; import java.util.Hashtable; import java.util.Vector; import java.util.ArrayList; import javax.swing.SwingUtilities; import org.openide.TopManager; import org.openide.debugger.Debugger; import org.openide.debugger.DebuggerException; import org.openide.debugger.Watch; import org.openide.actions.AddWatchAction; import org.openide.actions.PropertiesAction; import org.openide.actions.ToolsAction; import org.openide.util.actions.SystemAction; import org.openide.util.actions.CallableSystemAction; import org.openide.util.NbBundle; import org.openide.nodes.Node; import org.openide.nodes.Children; import org.openide.nodes.AbstractNode; import org.netbeans.modules.debugger.support.AbstractDebugger; import org.netbeans.modules.debugger.support.DebuggerModule; import org.netbeans.modules.debugger.support.AbstractVariable; import org.netbeans.modules.debugger.support.AbstractWatch; import org.netbeans.modules.debugger.support.DebuggerAdapter; import org.netbeans.modules.debugger.support.VariableImpl; import org.netbeans.modules.debugger.support.actions.DeleteAllCookie; import org.netbeans.modules.debugger.support.actions.DeleteAllAction; import org.netbeans.modules.debugger.support.util.Validator; /** * This class representates watches root as a Node. * This class is final only for performance reasons, * can be happily unfinaled if desired. * * @author Jan Jancura */ public final class WatchesRootNode extends AbstractNode implements VariableHome, DeleteAllCookie { // static variables .......................................................... /** generated Serialized Version UID */ static final long serialVersionUID = -3518528079657369038L; private static final String ICON_WATCHES = "/org/netbeans/core/resources/watches"; // NOI18N private static final String ICON_PENDING_WATCHES = "/org/netbeans/modules/debugger/resources/pendingWatches"; // NOI18N /** Popup menu actions. */ private static SystemAction[] staticActions; private static ResourceBundle bundle; // init ...................................................................... /** * Creates empty WatchesRootNode. */ public WatchesRootNode () { super (new WatchesRootChildren ()); ((WatchesRootChildren) getChildren ()).variableHome = this; String name = getLocalizedString ("CTL_Watches_group_root"); setDisplayName (name); setName (name); setIconBase (ICON_WATCHES); getCookieSet ().add (this); init (); } private DebuggerView getView () { return DebuggerModule.getViewFor (this); } private void init () { try { AbstractDebugger debugger = (AbstractDebugger) TopManager.getDefault ().getDebugger (); final Validator validator = debugger.getValidator (); debugger.getValidator ().addPropertyChangeListener ( new PropertyChangeListener () { public void propertyChange (PropertyChangeEvent e) { setIconBase ( validator.isValidated () ? ICON_WATCHES : ICON_PENDING_WATCHES ); /* setDisplayName ( validator.isValidated () ? getLocalizedString ("CTL_Watches_group_root") : getLocalizedString ("CTL_Watches_group_root_refresh") ); */ // PATCH, we must force the view to be repainted Node [] nodes = getChildren ().getNodes (); Node node = null; String displayName = null; if ((nodes != null) && (nodes.length > 0)) { node = nodes [0]; displayName = node.getDisplayName (); node.setDisplayName (displayName.concat (" ")); // NOI18N } DebuggerView view = getView (); if (view != null) { view.repaint (70); } if (node != null) node.setDisplayName (displayName); // end of PATCH } } ); } catch (DebuggerException e) { } } /** deserializes object */ private void readObject(java.io.ObjectInputStream obis) throws java.io.IOException, ClassNotFoundException, java.io.NotActiveException { obis.defaultReadObject (); init (); } // Node implementation ....................................................... /** Getter for set of actions that should be present in the * popup menu of this node. This set is used in construction of * menu returned from getContextMenu and specially when a menu for * more nodes is constructed. * * @return array of system actions that should be in popup menu */ public SystemAction[] getActions () { if (staticActions == null) staticActions = new SystemAction[] { SystemAction.get(AddWatchAction.class), null, SystemAction.get (DeleteAllAction.class), null, SystemAction.get(ToolsAction.class), SystemAction.get(PropertiesAction.class), }; return staticActions; } /** Obtain handle for this node (for serialization). * The handle can be serialized and {@link Handle#getNode} used after * deserialization to obtain the original node. * * @return the handle, or <code>null</code> if this node is not persistable */ public Node.Handle getHandle () { return new WatchesHandle (); } /** * Returns default action. */ public SystemAction getDefaultAction () { return SystemAction.get (AddWatchAction.class); } // DeleteAllCookie implementation ............................................ /** * Delete all breakpoints. */ public void deleteAll () { try { // obtain reference to the debugger instance AbstractDebugger debugger = (AbstractDebugger) TopManager.getDefault (). getDebugger (); debugger.removeAllWatches (); } catch (DebuggerException exc) { } } // other methods ............................................................. public void createVariable (AbstractVariable variable) { ((WatchesRootChildren) getChildren ()).addVariable ( (AbstractVariable) ((VariableImpl) variable).clone () ); } /** * @return localized string. */ static String getLocalizedString (String s) { if (bundle == null) bundle = NbBundle.getBundle (WatchesRootNode.class); return bundle.getString (s); } // innerclasses .............................................................. /** Special watches context subnodes (children) */ static final class WatchesRootChildren extends Children.Array { /** Where to add variables. */ private VariableHome variableHome; /** * @associates WatchNode */ private Hashtable watches = new Hashtable (); /** Initializes children - creates nodes for existing watches */ protected java.util.Collection initCollection () { try { // obtain reference to the debugger instance final AbstractDebugger debugger = (AbstractDebugger) TopManager. getDefault ().getDebugger (); // create nodes for watches Watch[] watches = debugger.getWatches (); int i, k = watches.length; ArrayList n = new ArrayList (k); for (i = 0; i < k; i++) { WatchNode watchNode = new WatchNode ( variableHome, (AbstractWatch) watches [i] ); n.add (watchNode); this.watches.put (watches [i], watchNode); } debugger.addDebuggerListener (new DebuggerAdapter () { public void watchAdded (AbstractWatch watch) { addWatch (watch); } public void watchRemoved (AbstractWatch watch) { removeWatch (watch); } }); debugger.addPropertyChangeListener (new PropertyChangeListener () { public void propertyChange (PropertyChangeEvent e) { if (debugger.getState () != debugger.DEBUGGER_NOT_RUNNING) return; // remove all variables Node[] nn = getNodes (); int j, l = nn.length; Vector v = new Vector (l); for (j = 0; j < l; j++) if (!(nn [j] instanceof WatchNode)) v.addElement (nn [j]); nn = (Node[]) v.toArray (new Node [v.size ()]); remove (nn); } }); return n; } catch (DebuggerException exc) { return new ArrayList (); } } /** Adds new subnode representing given watch */ private void addWatch (AbstractWatch watch) { WatchNode watchNode = new WatchNode (variableHome, watch); watches.put (watch, watchNode); add (new Node[] {watchNode}); } /** Adds new subnode representing given watch */ private void addVariable (AbstractVariable variable) { add (new Node[] {new VariableNode (variableHome, variable, true)}); } /** Removes subnode which represents given watch */ private void removeWatch (AbstractWatch watch) { WatchNode watchNode = (WatchNode) watches.remove (watch); if (watchNode == null) return; remove (new Node[] {watchNode}); } /** Removes subnode which represents given watch */ void removeVariable (VariableNode variable) { remove (new Node[] {variable}); } } // end of WatchesRootNodeChildren inner class /** * Serializable node reference. */ private static class WatchesHandle implements Node.Handle { static final long serialVersionUID =-4518262478987259653L; /** Reconstitute the node for this handle. * * @return the node for this handle * @exception IOException if the node cannot be created */ public Node getNode () { return DebuggerModule.getWatchesRootNode (); } } } /* * Log * 10 Gandalf-post-FCS1.8.3.0 3/28/00 Daniel Prusa * 9 Gandalf 1.8 1/13/00 Daniel Prusa NOI18N * 8 Gandalf 1.7 1/3/00 Daniel Prusa bugfix for fixed watches * 7 Gandalf 1.6 11/8/99 Jan Jancura Somma classes renamed * 6 Gandalf 1.5 11/5/99 Jan Jancura Default action updated * 5 Gandalf 1.4 10/23/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 4 Gandalf 1.3 10/13/99 Jan Jancura Destroy action bug in * deleting watches deserializing of main window * 3 Gandalf 1.2 10/1/99 Jan Jancura Bug 3677 * 2 Gandalf 1.1 9/2/99 Jan Jancura * 1 Gandalf 1.0 8/17/99 Jan Jancura * $ */